home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / POLYSOLV.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-27  |  30.5 KB  |  1,688 lines

  1. /****************************************************************************
  2. *                polysolv.c
  3. *
  4. *  This file was written by Alexander Enzmann.  He wrote the code for
  5. *  4th-6th order shapes and generously provided us these enhancements.
  6. *
  7. *  from Persistence of Vision(tm) Ray Tracer
  8. *  Copyright 1996 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  NOTICE: This source code file is provided so that users may experiment
  11. *  with enhancements to POV-Ray and to port the software to platforms other 
  12. *  than those supported by the POV-Ray Team.  There are strict rules under
  13. *  which you are permitted to use this file.  The rules are in the file
  14. *  named POVLEGAL.DOC which should be distributed with this file. If 
  15. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  16. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  17. *  Forum.  The latest version of POV-Ray may be found there as well.
  18. *
  19. * This program is based on the popular DKB raytracer version 2.12.
  20. * DKBTrace was originally written by David K. Buck.
  21. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  22. *
  23. *****************************************************************************/
  24.  
  25. #include "frame.h"
  26. #include "povray.h"
  27. #include "povproto.h"
  28. #include "vector.h"
  29. #include "polysolv.h"
  30.  
  31.  
  32.  
  33. /*****************************************************************************
  34. * Local preprocessor defines
  35. ******************************************************************************/
  36.  
  37. #undef EPSILON
  38. #define EPSILON 1.0e-10
  39.  
  40. /*#define COEFF_LIMIT 1.0e-20 */
  41.  
  42. #define COEFF_LIMIT 1.0e-16 /*changed CEY 11/18/95 */
  43.  
  44. /*                  WARNING     WARNING    WARNING
  45.  
  46.    The following three constants have been defined so that quartic equations
  47.    will properly render on fpu/compiler combinations that only have 64 bit
  48.    IEEE precision.  Do not arbitrarily change any of these values.
  49.  
  50.    If you have a machine with a proper fpu/compiler combo - like a Mac with
  51.    a 68881, then use the native floating format (96 bits) and tune the
  52.    values for a little less tolerance: something like: factor1 = 1.0e15,
  53.    factor2 = -1.0e-7, factor3 = 1.0e-10.
  54.  
  55.    The meaning of the three constants are:
  56.       factor1 - the magnitude of difference between coefficients in a
  57.                 quartic equation at which the Sturmian root solver will
  58.                 kick in.  The Sturm solver is quite a bit slower than
  59.                 the algebraic solver, so the bigger this is, the faster
  60.                 the root solving will go.  The algebraic solver is less
  61.                 accurate so the bigger this is, the more likely you will
  62.                 get bad roots.
  63.  
  64.       factor2 - Tolerance value that defines how close the quartic equation
  65.                 is to being a square of a quadratic.  The closer this can
  66.                 get to zero before roots disappear, the less the chance
  67.                 you will get spurious roots.
  68.  
  69.       factor3 - Similar to factor2 at a later stage of the algebraic solver.
  70. */
  71. #define FUDGE_FACTOR1 1.0e12
  72. #define FUDGE_FACTOR2 -1.0e-5
  73. #define FUDGE_FACTOR3 1.0e-7
  74.  
  75. #define TWO_PI 6.283185207179586476925286766560
  76. #define TWO_PI_3  2.0943951023931954923084
  77. #define TWO_PI_43 4.1887902047863909846168
  78. #define MAX_ITERATIONS 50
  79. #define MAXPOW 32
  80.  
  81.  
  82.  
  83. /*****************************************************************************
  84. * Local typedefs
  85. ******************************************************************************/
  86.  
  87. typedef struct p
  88. {
  89.   int ord;
  90.   DBL coef[MAX_ORDER+1];
  91. }
  92. polynomial;
  93.  
  94.  
  95.  
  96. /*****************************************************************************
  97. * Local variables
  98. ******************************************************************************/
  99.  
  100.  
  101.  
  102. /*****************************************************************************
  103. * Static functions
  104. ******************************************************************************/
  105.  
  106. static int solve_quadratic PARAMS((DBL *x, DBL *y));
  107. static int solve_cubic PARAMS((DBL *x, DBL *y));
  108. static int solve_quartic PARAMS((DBL *x, DBL *y));
  109. static int polysolve PARAMS((int order, DBL *Coeffs, DBL *roots));
  110. static int modp PARAMS((polynomial *u, polynomial *v, polynomial *r));
  111. static int regula_falsa PARAMS((int order, DBL *coef, DBL a, DBL b, DBL *val));
  112. static int sbisect PARAMS((int np, polynomial *sseq, DBL min, DBL max, int atmin, int atmax, DBL *roots));
  113. static int numchanges PARAMS((int np, polynomial *sseq, DBL a));
  114. static DBL polyeval PARAMS((DBL x, int n, DBL *Coeffs));
  115. static int buildsturm PARAMS((int ord, polynomial *sseq));
  116. static int visible_roots PARAMS((int np, polynomial *sseq, int *atneg, int *atpos));
  117. static int difficult_coeffs PARAMS((int n, DBL *x));
  118.  
  119.  
  120.  
  121. /*****************************************************************************
  122. *
  123. * FUNCTION
  124. *
  125. *   modp
  126. *
  127. * INPUT
  128. *   
  129. * OUTPUT
  130. *   
  131. * RETURNS
  132. *   
  133. * AUTHOR
  134. *
  135. *   Alexander Enzmann
  136. *   
  137. * DESCRIPTION
  138. *
  139. *   Calculates the modulus of u(x) / v(x) leaving it in r.
  140. *   It returns 0 if r(x) is a constant.
  141. *
  142. *   NOTE: This function assumes the leading coefficient of v is 1 or -1.
  143. *
  144. * CHANGES
  145. *
  146. *   -
  147. *
  148. ******************************************************************************/
  149.  
  150. static int modp(u, v, r)
  151. polynomial *u, *v, *r;
  152. {
  153.   int i, k, j;
  154.  
  155.   for (i = 0; i <u->ord; i++)
  156.   {
  157.     r[i] = u[i];
  158.   }
  159.  
  160.   if (v->coef[v->ord] < 0.0)
  161.   {
  162.     for (k = u->ord - v->ord - 1; k >= 0; k -= 2)
  163.     {
  164.       r->coef[k] = -r->coef[k];
  165.     }
  166.  
  167.     for (k = u->ord - v->ord; k >= 0; k--)
  168.     {
  169.       for (j = v->ord + k - 1; j >= k; j--)
  170.       {
  171.         r->coef[j] = -r->coef[j] - r->coef[v->ord + k] * v->coef[j - k];
  172.       }
  173.     }
  174.   }
  175.   else
  176.   {
  177.     for (k = u->ord - v->ord; k >= 0; k--)
  178.     {
  179.       for (j = v->ord + k - 1; j >= k; j--)
  180.       {
  181.         r->coef[j] -= r->coef[v->ord + k] * v->coef[j - k];
  182.       }
  183.     }
  184.   }
  185.  
  186.   k = v->ord - 1;
  187.  
  188.   while (k >= 0 && fabs(r->coef[k]) < COEFF_LIMIT)
  189.   {
  190.     r->coef[k] = 0.0;
  191.     k--;
  192.   }
  193.  
  194.   r->ord = (k < 0) ? 0 : k;
  195.  
  196.   return(r->ord);
  197. }
  198.  
  199.  
  200.  
  201. /*****************************************************************************
  202. *
  203. * FUNCTION
  204. *
  205. *   buildsturm
  206. *
  207. * INPUT
  208. *   
  209. * OUTPUT
  210. *   
  211. * RETURNS
  212. *   
  213. * AUTHOR
  214. *
  215. *   Alexander Enzmann
  216. *   
  217. * DESCRIPTION
  218. *
  219. *   Build the sturmian sequence for a polynomial.
  220. *
  221. * CHANGES
  222. *
  223. *   -
  224. *
  225. ******************************************************************************/
  226.  
  227. static int buildsturm(ord, sseq)
  228. int ord;
  229. polynomial *sseq;
  230. {
  231.   int i;
  232.   DBL f, *fp, *fc;
  233.   polynomial *sp;
  234.  
  235.   sseq[0].ord = ord;
  236.   sseq[1].ord = ord - 1;
  237.  
  238.   /* calculate the derivative and normalize the leading coefficient. */
  239.  
  240.   f = fabs(sseq[0].coef[ord] * ord);
  241.   fp = sseq[1].coef;
  242.   fc = sseq[0].coef + 1;
  243.  
  244.   for (i = 1; i <= ord; i++)
  245.   {
  246.     *fp++ = *fc++ * i / f;
  247.   }
  248.  
  249.   /* construct the rest of the Sturm sequence */
  250.  
  251.   for (sp = sseq + 2;modp(sp - 2, sp - 1, sp); sp++)
  252.   {
  253.     /* reverse the sign and normalize */
  254.  
  255.     f = -fabs(sp->coef[sp->ord]);
  256.  
  257.     for (fp = &sp->coef[sp->ord]; fp >= sp->coef; fp--)
  258.     {
  259.       *fp /= f;
  260.     }
  261.   }
  262.  
  263.   /* reverse the sign */
  264.  
  265.   sp->coef[0] = -sp->coef[0];
  266.  
  267.   return(sp - sseq);
  268. }
  269.  
  270.  
  271.  
  272. /*****************************************************************************
  273. *
  274. * FUNCTION
  275. *
  276. *   visible_roots
  277. *
  278. * INPUT
  279. *   
  280. * OUTPUT
  281. *   
  282. * RETURNS
  283. *   
  284. * AUTHOR
  285. *
  286. *   Alexander Enzmann
  287. *   
  288. * DESCRIPTION
  289. *
  290. *   Find out how many visible intersections there are.
  291. *
  292. * CHANGES
  293. *
  294. *   -
  295. *
  296. ******************************************************************************/
  297.  
  298. static int visible_roots(np, sseq, atzer, atpos)
  299. int np;
  300. polynomial *sseq;
  301. int *atzer, *atpos;
  302. {
  303.   int atposinf, atzero;
  304.   polynomial *s;
  305.   DBL f, lf;
  306.  
  307.   atposinf = atzero = 0;
  308.  
  309.   /* changes at positve infinity */
  310.  
  311.   lf = sseq[0].coef[sseq[0].ord];
  312.  
  313.   for (s = sseq + 1; s <= sseq + np; s++)
  314.   {
  315.     f = s->coef[s->ord];
  316.  
  317.     if (lf == 0.0 || lf * f < 0)
  318.     {
  319.       atposinf++;
  320.     }
  321.  
  322.     lf = f;
  323.   }
  324.  
  325.   /* Changes at zero */
  326.  
  327.   lf = sseq[0].coef[0];
  328.  
  329.   for (s = sseq+1; s <= sseq + np; s++)
  330.   {
  331.     f = s->coef[0];
  332.  
  333.     if (lf == 0.0 || lf * f < 0)
  334.     {
  335.       atzero++;
  336.     }
  337.  
  338.     lf = f;
  339.   }
  340.  
  341.   *atzer = atzero;
  342.   *atpos = atposinf;
  343.  
  344.   return(atzero - atposinf);
  345. }
  346.  
  347.  
  348.  
  349. /*****************************************************************************
  350. *
  351. * FUNCTION
  352. *
  353. *   numchanges
  354. *
  355. * INPUT
  356. *   
  357. * OUTPUT
  358. *   
  359. * RETURNS
  360. *   
  361. * AUTHOR
  362. *
  363. *   Alexander Enzmann
  364. *   
  365. * DESCRIPTION
  366. *
  367. *   Return the number of sign changes in the Sturm sequence in
  368. *   sseq at the value a.
  369. *
  370. * CHANGES
  371. *
  372. *   -
  373. *
  374. ******************************************************************************/
  375.  
  376. static int numchanges(np, sseq, a)
  377. int np;
  378. polynomial *sseq;
  379. DBL a;
  380. {
  381.   int changes;
  382.   DBL f, lf;
  383.   polynomial   *s;
  384.   changes = 0;
  385.  
  386.   lf = polyeval(a, sseq[0].ord, sseq[0].coef);
  387.  
  388.   for (s = sseq + 1; s <= sseq + np; s++)
  389.   {
  390.     f = polyeval(a, s->ord, s->coef);
  391.  
  392.     if (lf == 0.0 || lf * f < 0)
  393.     {
  394.       changes++;
  395.     }
  396.  
  397.     lf = f;
  398.   }
  399.  
  400.   return(changes);
  401. }
  402.  
  403.  
  404.  
  405. /*****************************************************************************
  406. *
  407. * FUNCTION
  408. *
  409. *   sbisect
  410. *
  411. * INPUT
  412. *   
  413. * OUTPUT
  414. *   
  415. * RETURNS
  416. *   
  417. * AUTHOR
  418. *
  419. *   Alexander Enzmann
  420. *   
  421. * DESCRIPTION
  422. *
  423. *   Uses a bisection based on the sturm sequence for the polynomial
  424. *   described in sseq to isolate intervals in which roots occur,
  425. *   the roots are returned in the roots array in order of magnitude.
  426. *
  427. *   NOTE: This routine has one severe bug: When the interval containing the
  428. *         root [min, max] has a root at one of its endpoints, as well as one
  429. *         within the interval, the root at the endpoint will be returned
  430. *         rather than the one inside.
  431. *
  432. * CHANGES
  433. *
  434. *   -
  435. *
  436. ******************************************************************************/
  437.  
  438. static int sbisect(np, sseq, min_value, max_value, atmin, atmax, roots)
  439. int np;
  440. polynomial *sseq;
  441. DBL min_value, max_value;
  442. int atmin, atmax;
  443. DBL *roots;
  444. {
  445.   DBL mid;
  446.   int n1, n2, its, atmid;
  447.  
  448.   if ((atmin - atmax) == 1)
  449.   {
  450.     /* first try using regula-falsa to find the root.  */
  451.  
  452.     if (regula_falsa(sseq->ord, sseq->coef, min_value, max_value, roots))
  453.     {
  454.       return(1);
  455.     }
  456.     else
  457.     {
  458.       /* That failed, so now find it by bisection */
  459.  
  460.       for (its = 0; its < MAX_ITERATIONS; its++)
  461.       {
  462.         mid = (min_value + max_value) / 2;
  463.  
  464.         atmid = numchanges(np, sseq, mid);
  465.  
  466.         if (fabs(mid) > EPSILON)
  467.         {
  468.           if (fabs((max_value - min_value) / mid) < EPSILON)
  469.           {
  470.             roots[0] = mid;
  471.  
  472.             return(1);
  473.           }
  474.         }
  475.         else
  476.         {
  477.           if (fabs(max_value - min_value) < EPSILON)
  478.           {
  479.             roots[0] = mid;
  480.  
  481.             return(1);
  482.           }
  483.         }
  484.  
  485.         if ((atmin - atmid) == 0)
  486.         {
  487.           min_value = mid;
  488.         }
  489.         else
  490.         {
  491.           max_value = mid;
  492.         }
  493.       }
  494.  
  495.       /* Bisection took too long - just return what we got */
  496.  
  497.       roots[0] = mid;
  498.  
  499.       return(1);
  500.     }
  501.   }
  502.  
  503.   /* There is more than one root in the interval.
  504.      Bisect to find new intervals. */
  505.  
  506.   for (its = 0; its < MAX_ITERATIONS; its++)
  507.   {
  508.     mid = (min_value + max_value) / 2;
  509.     atmid = numchanges(np, sseq, mid);
  510.  
  511.     n1 = atmin - atmid;
  512.     n2 = atmid - atmax;
  513.  
  514.     if ((n1 != 0) && (n2 != 0))
  515.     {
  516.       n1 = sbisect(np, sseq, min_value, mid, atmin, atmid, roots);
  517.       n2 = sbisect(np, sseq, mid, max_value, atmid, atmax, &roots[n1]);
  518.  
  519.       return(n1 + n2);
  520.     }
  521.  
  522.     if (n1 == 0)
  523.     {
  524.       min_value = mid;
  525.     }
  526.     else
  527.     {
  528.       max_value = mid;
  529.     }
  530.   }
  531.  
  532.   /* Took too long to bisect.  Just return what we got. */
  533.  
  534.   roots[0] = mid;
  535.  
  536.   return(1);
  537. }
  538.  
  539.  
  540.  
  541. /*****************************************************************************
  542. *
  543. * FUNCTION
  544. *
  545. *   polyeval
  546. *
  547. * INPUT
  548. *   
  549. * OUTPUT
  550. *   
  551. * RETURNS
  552. *   
  553. * AUTHOR
  554. *
  555. *   Alexander Enzmann
  556. *   
  557. * DESCRIPTION
  558. *
  559. *   -
  560. *
  561. * CHANGES
  562. *
  563. *   -
  564. *
  565. ******************************************************************************/
  566.  
  567. static DBL polyeval(x, n, Coeffs)
  568. DBL x, *Coeffs;
  569. int n;
  570. {
  571.   register int i;
  572.   DBL val;
  573.  
  574.   val = Coeffs[n];
  575.  
  576.   for (i = n-1; i >= 0; i--)
  577.   {
  578.     val = val * x + Coeffs[i];
  579.   }
  580.  
  581.   return(val);
  582. }
  583.  
  584.  
  585.  
  586. /*****************************************************************************
  587. *
  588. * FUNCTION
  589. *
  590. *   regular_falsa
  591. *
  592. * INPUT
  593. *   
  594. * OUTPUT
  595. *   
  596. * RETURNS
  597. *   
  598. * AUTHOR
  599. *
  600. *   Alexander Enzmann
  601. *   
  602. * DESCRIPTION
  603. *
  604. *   Close in on a root by using regula-falsa.
  605. *
  606. * CHANGES
  607. *
  608. *   -
  609. *
  610. ******************************************************************************/
  611.  
  612. static int regula_falsa(order, coef, a, b, val)
  613. int order;
  614. DBL *coef;
  615. DBL a, b, *val;
  616. {
  617.   int its;
  618.   DBL fa, fb, x, fx, lfx;
  619.  
  620.   fa = polyeval(a, order, coef);
  621.   fb = polyeval(b, order, coef);
  622.  
  623.   if (fa * fb > 0.0)
  624.   {
  625.     return 0;
  626.   }
  627.  
  628.   if (fabs(fa) < COEFF_LIMIT)
  629.   {
  630.     *val = a;
  631.  
  632.     return(1);
  633.   }
  634.  
  635.   if (fabs(fb) < COEFF_LIMIT)
  636.   {
  637.     *val = b;
  638.  
  639.     return(1);
  640.   }
  641.  
  642.   lfx = fa;
  643.  
  644.   for (its = 0; its < MAX_ITERATIONS; its++)
  645.   {
  646.     x = (fb * a - fa * b) / (fb - fa);
  647.  
  648.     fx = polyeval(x, order, coef);
  649.  
  650.     if (fabs(x) > EPSILON)
  651.     {
  652.       if (fabs(fx / x) < EPSILON)
  653.       {
  654.         *val = x;
  655.  
  656.         return(1);
  657.       }
  658.     }
  659.     else
  660.     {
  661.       if (fabs(fx) < EPSILON)
  662.       {
  663.         *val = x;
  664.  
  665.         return(1);
  666.       }
  667.     }
  668.  
  669.     if (fa < 0)
  670.     {
  671.       if (fx < 0)
  672.       {
  673.         a = x;
  674.         fa = fx;
  675.  
  676.         if ((lfx * fx) > 0)
  677.         {
  678.           fb /= 2;
  679.         }
  680.       }
  681.       else
  682.       {
  683.         b = x;
  684.         fb = fx;
  685.  
  686.         if ((lfx * fx) > 0)
  687.         {
  688.           fa /= 2;
  689.         }
  690.       }
  691.     }
  692.     else
  693.     {
  694.       if (fx < 0)
  695.       {
  696.         b = x;
  697.         fb = fx;
  698.  
  699.         if ((lfx * fx) > 0)
  700.         {
  701.           fa /= 2;
  702.         }
  703.       }
  704.       else
  705.       {
  706.         a = x;
  707.         fa = fx;
  708.  
  709.         if ((lfx * fx) > 0)
  710.         {
  711.           fb /= 2;
  712.         }
  713.       }
  714.     }
  715.  
  716.     /* Check for underflow in the domain */
  717.  
  718.     if (fabs(b-a) < EPSILON)
  719.     {
  720.       *val = x;
  721.  
  722.       return(1);
  723.     }
  724.  
  725.     lfx = fx;
  726.   }
  727.  
  728.   return(0);
  729. }
  730.  
  731.  
  732.  
  733. /*****************************************************************************
  734. *
  735. * FUNCTION
  736. *
  737. *   solve_quadratic
  738. *
  739. * INPUT
  740. *   
  741. * OUTPUT
  742. *   
  743. * RETURNS
  744. *   
  745. * AUTHOR
  746. *
  747. *   Alexander Enzmann
  748. *   
  749. * DESCRIPTION
  750. *
  751. *   Solve the quadratic equation:
  752. *
  753. *     x[0] * x^2 + x[1] * x + x[2] = 0.
  754. *
  755. *   The value returned by this function is the number of real roots.
  756. *   The roots themselves are returned in y[0], y[1].
  757. *
  758. * CHANGES
  759. *
  760. *   -
  761. *
  762. ******************************************************************************/
  763.  
  764. static int solve_quadratic(x, y)
  765. DBL *x, *y;
  766. {
  767.   DBL d, t, a, b, c;
  768.  
  769.   a = x[0];
  770.   b = -x[1];
  771.   c = x[2];
  772.  
  773.   if (a == 0.0)
  774.   {
  775.     if (b == 0.0)
  776.     {
  777.       return(0);
  778.     }
  779.  
  780.     y[0] = c / b;
  781.  
  782.     return(1);
  783.   }
  784.  
  785.   d = b * b - 4.0 * a * c;
  786.  
  787.   /* Treat values of d around 0 as 0. */
  788.  
  789.   if (d < -EPSILON)
  790.   {
  791.     return(0);
  792.   }
  793.   else
  794.   {
  795.     if (d < COEFF_LIMIT)
  796.     {
  797.       y[0] = 0.5 * b / a;
  798.  
  799.       return(1);
  800.     }
  801.   }
  802.  
  803.   d = sqrt(d);
  804.  
  805.   t = 2.0 * a;
  806.  
  807.   y[0] = (b + d) / t;
  808.   y[1] = (b - d) / t;
  809.  
  810.   return(2);
  811. }
  812.  
  813.  
  814.  
  815. /*****************************************************************************
  816. *
  817. * FUNCTION
  818. *
  819. *   solve_cubic
  820. *
  821. * INPUT
  822. *   
  823. * OUTPUT
  824. *   
  825. * RETURNS
  826. *   
  827. * AUTHOR
  828. *
  829. *   Alexander Enzmann
  830. *   
  831. * DESCRIPTION
  832. *
  833. *
  834. *   Solve the cubic equation:
  835. *
  836. *     x[0] * x^3 + x[1] * x^2 + x[2] * x + x[3] = 0.
  837. *
  838. *   The result of this function is an integer that tells how many real
  839. *   roots exist.  Determination of how many are distinct is up to the
  840. *   process that calls this routine.  The roots that exist are stored
  841. *   in (y[0], y[1], y[2]).
  842. *
  843. *   NOTE: This function relies very heavily on trigonometric functions and
  844. *         the square root function.  If an alternative solution is found
  845. *         that does not rely on transcendentals this code will be replaced.
  846. *
  847. * CHANGES
  848. *
  849. *   -
  850. *
  851. ******************************************************************************/
  852.  
  853. static int solve_cubic(x, y)
  854. DBL *x, *y;
  855. {
  856.   DBL Q, R, Q3, R2, sQ, d, an, theta;
  857.   DBL A2, a0, a1, a2, a3;
  858.  
  859.   a0 = x[0];
  860.  
  861.   if (a0 == 0.0)
  862.   {
  863.     return(solve_quadratic(&x[1], y));
  864.   }
  865.   else
  866.   {
  867.     if (a0 != 1.0)
  868.     {
  869.       a1 = x[1] / a0;
  870.       a2 = x[2] / a0;
  871.       a3 = x[3] / a0;
  872.     }
  873.     else
  874.     {
  875.       a1 = x[1];
  876.       a2 = x[2];
  877.       a3 = x[3];
  878.     }
  879.   }
  880.  
  881.   A2 = a1 * a1;
  882.  
  883.   Q = (A2 - 3.0 * a2) / 9.0;
  884.  
  885.   /* Modified to save some multiplications and to avoid a floating point
  886.      exception that occured with DJGPP and full optimization. [DB 8/94] */
  887.  
  888.   R = (a1 * (A2 - 4.5 * a2) + 13.5 * a3) / 27.0;
  889.  
  890.   Q3 = Q * Q * Q;
  891.  
  892.   R2 = R * R;
  893.  
  894.   d = Q3 - R2;
  895.  
  896.   an = a1 / 3.0;
  897.  
  898.   if (d >= 0.0)
  899.   {
  900.     /* Three real roots. */
  901.  
  902.     d = R / sqrt(Q3);
  903.  
  904.     theta = acos(d) / 3.0;
  905.  
  906.     sQ = -2.0 * sqrt(Q);
  907.  
  908.     y[0] = sQ * cos(theta) - an;
  909.     y[1] = sQ * cos(theta + TWO_PI_3) - an;
  910.     y[2] = sQ * cos(theta + TWO_PI_43) - an;
  911.  
  912.     return(3);
  913.   }
  914.   else
  915.   {
  916.     sQ = pow(sqrt(R2 - Q3) + fabs(R), 1.0 / 3.0);
  917.  
  918.     if (R < 0)
  919.     {
  920.       y[0] = (sQ + Q / sQ) - an;
  921.     }
  922.     else
  923.     {
  924.       y[0] = -(sQ + Q / sQ) - an;
  925.     }
  926.  
  927.     return(1);
  928.   }
  929. }
  930.  
  931. #ifdef USE_NEW_DIFFICULT_COEFFS
  932.  
  933. /*****************************************************************************
  934. *
  935. * FUNCTION
  936. *
  937. *   difficult_coeffs
  938. *
  939. * INPUT
  940. *   
  941. * OUTPUT
  942. *   
  943. * RETURNS
  944. *   
  945. * AUTHOR
  946. *
  947. *   Alexander Enzmann
  948. *   
  949. * DESCRIPTION
  950. *
  951. *   Test to see if any coeffs are more than 6 orders of magnitude
  952. *   larger than the smallest.
  953. *
  954. * CHANGES
  955. *
  956. *   -
  957. *
  958. ******************************************************************************/
  959.  
  960. static int difficult_coeffs(n, x)
  961. int n;
  962. DBL *x;
  963. {
  964.   int i, flag = 0;
  965.   DBL t, biggest;
  966.  
  967.   biggest = fabs(x[0]);
  968.  
  969.   for (i = 1; i <= n; i++)
  970.   {
  971.     t = fabs(x[i]);
  972.  
  973.     if (t > biggest)
  974.     {
  975.       biggest = t;
  976.     }
  977.   }
  978.  
  979.   /* Everything is zero no sense in doing any more */
  980.  
  981.   if (biggest == 0.0)
  982.   {
  983.     return(0);
  984.   }
  985.  
  986.   for (i = 0; i <= n; i++)
  987.   {
  988.     if (x[i] != 0.0)
  989.     {
  990.       if (fabs(biggest / x[i]) > FUDGE_FACTOR1)
  991.       {
  992.         x[i] = 0.0;
  993.         flag = 1;
  994.       }
  995.     }
  996.   }
  997.  
  998.   return(flag);
  999. }
  1000. #else
  1001. /*****************************************************************************
  1002. *
  1003. * FUNCTION
  1004. *
  1005. *   difficult_coeffs
  1006. *
  1007. * INPUT
  1008. *   
  1009. * OUTPUT
  1010. *   
  1011. * RETURNS
  1012. *   
  1013. * AUTHOR
  1014. *
  1015. *   Alexander Enzmann
  1016. *   
  1017. * DESCRIPTION
  1018. *
  1019. *   Test to see if any coeffs are more than 6 orders of magnitude
  1020. *   larger than the smallest (function from POV 1.0) [DB 8/94].
  1021. *
  1022. * CHANGES
  1023. *
  1024. *   -
  1025. *
  1026. ******************************************************************************/
  1027.  
  1028. static int difficult_coeffs(n, x)
  1029. int n;
  1030. DBL *x;
  1031. {
  1032.   int i;
  1033.   DBL biggest;
  1034.  
  1035.   biggest = 0.0;
  1036.  
  1037.   for (i = 0; i <= n; i++)
  1038.   {
  1039.     if (fabs(x[i]) > biggest)
  1040.     {
  1041.       biggest = x[i];
  1042.     }
  1043.   }
  1044.  
  1045.   /* Everything is zero no sense in doing any more */
  1046.  
  1047.   if (biggest == 0.0)
  1048.   {
  1049.     return(0);
  1050.   }
  1051.  
  1052.   for (i = 0; i <= n; i++)
  1053.   {
  1054.     if (x[i] != 0.0)
  1055.     {
  1056.       if (fabs(biggest / x[i]) > FUDGE_FACTOR1)
  1057.       {
  1058.         return(1);
  1059.       }
  1060.     }
  1061.   }
  1062.  
  1063.   return(0);
  1064. }
  1065.  
  1066. #endif
  1067.  
  1068. #ifdef TEST_SOLVER
  1069. /*****************************************************************************
  1070. *
  1071. * FUNCTION
  1072. *
  1073. *   solve_quartic
  1074. *
  1075. * INPUT
  1076. *   
  1077. * OUTPUT
  1078. *   
  1079. * RETURNS
  1080. *   
  1081. * AUTHOR
  1082. *
  1083. *   Alexander Enzmann
  1084. *   
  1085. * DESCRIPTION
  1086. *
  1087. *   The old way of solving quartics algebraically.
  1088. *   This is an adaptation of the method of Lodovico Ferrari (Circa 1731).
  1089. *
  1090. * CHANGES
  1091. *
  1092. *   -
  1093. *
  1094. ******************************************************************************/
  1095.  
  1096. static int solve_quartic(x, results)
  1097. DBL *x, *results;
  1098. {
  1099.   DBL cubic[4], roots[3];
  1100.   DBL a0, a1, y, d1, x1, t1, t2;
  1101.   DBL c0, c1, c2, c3, c4, d2, q1, q2;
  1102.   int i;
  1103.  
  1104.   c0 = x[0];
  1105.  
  1106.   if (c0 != 1.0)
  1107.   {
  1108.     c1 = x[1] / c0;
  1109.     c2 = x[2] / c0;
  1110.     c3 = x[3] / c0;
  1111.     c4 = x[4] / c0;
  1112.   }
  1113.   else
  1114.   {
  1115.     c1 = x[1];
  1116.     c2 = x[2];
  1117.     c3 = x[3];
  1118.     c4 = x[4];
  1119.   }
  1120.  
  1121.   /* The first step is to take the original equation:
  1122.  
  1123.        x^4 + b*x^3 + c*x^2 + d*x + e = 0
  1124.  
  1125.      and rewrite it as:
  1126.  
  1127.        x^4 + b*x^3 = -c*x^2 - d*x - e,
  1128.  
  1129.      adding (b*x/2)^2 + (x^2 + b*x/2)y + y^2/4 to each side gives a
  1130.      perfect square on the lhs:
  1131.  
  1132.        (x^2 + b*x/2 + y/2)^2 = (b^2/4 - c + y)x^2 + (b*y/2 - d)x + y^2/4 - e
  1133.  
  1134.      By choosing the appropriate value for y, the rhs can be made a perfect
  1135.      square also.  This value is found when the rhs is treated as a quadratic
  1136.      in x with the discriminant equal to 0.  This will be true when:
  1137.  
  1138.        (b*y/2 - d)^2 - 4.0 * (b^2/4 - c*y)*(y^2/4 - e) = 0, or
  1139.  
  1140.        y^3 - c*y^2 + (b*d - 4*e)*y - b^2*e + 4*c*e - d^2 = 0.
  1141.  
  1142.      This is called the resolvent of the quartic equation.  */
  1143.  
  1144.   a0 = 4.0 * c4;
  1145.  
  1146.   cubic[0] = 1.0;
  1147.   cubic[1] = -1.0 * c2;
  1148.   cubic[2] = c1 * c3 - a0;
  1149.   cubic[3] = a0 * c2 - c1 * c1 * c4 - c3 * c3;
  1150.  
  1151.   i = solve_cubic(&cubic[0], &roots[0]);
  1152.  
  1153.   if (i > 0)
  1154.   {
  1155.     y = roots[0];
  1156.   }
  1157.   else
  1158.   {
  1159.     return(0);
  1160.   }
  1161.  
  1162.   /* What we are left with is a quadratic squared on the lhs and a
  1163.      linear term on the right.  The linear term has one of two signs,
  1164.      take each and add it to the lhs.  The form of the quartic is now:
  1165.  
  1166.        a' = b^2/4 - c + y,    b' = b*y/2 - d, (from rhs quadritic above)
  1167.  
  1168.        (x^2 + b*x/2 + y/2) = +sqrt(a'*(x + 1/2 * b'/a')^2), and
  1169.        (x^2 + b*x/2 + y/2) = -sqrt(a'*(x + 1/2 * b'/a')^2).
  1170.  
  1171.      By taking the linear term from each of the right hand sides and
  1172.      adding to the appropriate part of the left hand side, two quadratic
  1173.      formulas are created.  By solving each of these the four roots of
  1174.      the quartic are determined.
  1175.   */
  1176.  
  1177.   i = 0;
  1178.  
  1179.   a0 = c1 / 2.0;
  1180.   a1 = y / 2.0;
  1181.  
  1182.   t1 = a0 * a0 - c2 + y;
  1183.  
  1184.   if (t1 < 0.0)
  1185.   {
  1186.     if (t1 > FUDGE_FACTOR2)
  1187.     {
  1188.       t1 = 0.0;
  1189.     }
  1190.     else
  1191.     {
  1192.       /* First Special case, a' < 0 means all roots are complex. */
  1193.  
  1194.       return(0);
  1195.       }
  1196.     }
  1197.   }
  1198.  
  1199.   if (t1 < FUDGE_FACTOR3)
  1200.   {
  1201.     /* Second special case, the "x" term on the right hand side above
  1202.        has vanished.  In this case:
  1203.  
  1204.          (x^2 + b*x/2 + y/2) = +sqrt(y^2/4 - e), and
  1205.          (x^2 + b*x/2 + y/2) = -sqrt(y^2/4 - e).  */
  1206.  
  1207.     t2 = a1 * a1 - c4;
  1208.  
  1209.     if (t2 < 0.0)
  1210.     {
  1211.       return(0);
  1212.     }
  1213.  
  1214.     x1 = 0.0;
  1215.     d1 = sqrt(t2);
  1216.   }
  1217.   else
  1218.   {
  1219.     x1 = sqrt(t1);
  1220.     d1 = 0.5 * (a0 * y - c3) / x1;
  1221.   }
  1222.  
  1223.   /* Solve the first quadratic */
  1224.  
  1225.   q1 = -a0 - x1;
  1226.   q2 = a1 + d1;
  1227.   d2 = q1 * q1 - 4.0 * q2;
  1228.  
  1229.   if (d2 >= 0.0)
  1230.   {
  1231.     d2 = sqrt(d2);
  1232.  
  1233.     results[0] = 0.5 * (q1 + d2);
  1234.     results[1] = 0.5 * (q1 - d2);
  1235.  
  1236.     i = 2;
  1237.   }
  1238.  
  1239.   /* Solve the second quadratic */
  1240.  
  1241.   q1 = q1 + x1 + x1;
  1242.   q2 = a1 - d1;
  1243.   d2 = q1 * q1 - 4.0 * q2;
  1244.  
  1245.   if (d2 >= 0.0)
  1246.   {
  1247.     d2 = sqrt(d2);
  1248.  
  1249.     results[i++] = 0.5 * (q1 + d2);
  1250.     results[i++] = 0.5 * (q1 - d2);
  1251.   }
  1252.  
  1253.   return(i);
  1254. }
  1255. #else
  1256. /*****************************************************************************
  1257. *
  1258. * FUNCTION
  1259. *
  1260. *   solve_quartic
  1261. *
  1262. * INPUT
  1263. *   
  1264. * OUTPUT
  1265. *   
  1266. * RETURNS
  1267. *   
  1268. * AUTHOR
  1269. *
  1270. *   Alexander Enzmann
  1271. *   
  1272. * DESCRIPTION
  1273. *
  1274. *   Solve a quartic using the method of Francois Vieta (Circa 1735).
  1275. *
  1276. * CHANGES
  1277. *
  1278. *   -
  1279. *
  1280. ******************************************************************************/
  1281.  
  1282. static int solve_quartic(x, results)
  1283. DBL *x, *results;
  1284. {
  1285.   DBL cubic[4], roots[3];
  1286.   DBL c12, z, p, q, q1, q2, r, d1, d2;
  1287.   DBL c0, c1, c2, c3, c4;
  1288.   int i;
  1289.  
  1290.   /* Make sure the quartic has a leading coefficient of 1.0 */
  1291.  
  1292.   c0 = x[0];
  1293.  
  1294.   if (c0 != 1.0)
  1295.   {
  1296.     c1 = x[1] / c0;
  1297.     c2 = x[2] / c0;
  1298.     c3 = x[3] / c0;
  1299.     c4 = x[4] / c0;
  1300.   }
  1301.   else
  1302.   {
  1303.     c1 = x[1];
  1304.     c2 = x[2];
  1305.     c3 = x[3];
  1306.     c4 = x[4];
  1307.   }
  1308.  
  1309.   /* Compute the cubic resolvant */
  1310.  
  1311.   c12 = c1 * c1;
  1312.   p = -0.375 * c12 + c2;
  1313.   q = 0.125 * c12 * c1 - 0.5 * c1 * c2 + c3;
  1314.   r = -0.01171875 * c12 * c12 + 0.0625 * c12 * c2 - 0.25 * c1 * c3 + c4;
  1315.  
  1316.   cubic[0] = 1.0;
  1317.   cubic[1] = -0.5 * p;
  1318.   cubic[2] = -r;
  1319.   cubic[3] = 0.5 * r * p - 0.125 * q * q;
  1320.  
  1321.   i = solve_cubic(cubic, roots);
  1322.  
  1323.   if (i > 0)
  1324.   {
  1325.     z = roots[0];
  1326.   }
  1327.   else
  1328.   {
  1329.     return(0);
  1330.   }
  1331.  
  1332.   d1 = 2.0 * z - p;
  1333.  
  1334.   if (d1 < 0.0)
  1335.   {
  1336.     if (d1 > -EPSILON)
  1337.     {
  1338.       d1 = 0.0;
  1339.     }
  1340.     else
  1341.     {
  1342.       return(0);
  1343.     }
  1344.   }
  1345.  
  1346.   if (d1 < EPSILON)
  1347.   {
  1348.     d2 = z * z - r;
  1349.  
  1350.     if (d2 < 0.0)
  1351.     {
  1352.       return(0);
  1353.     }
  1354.  
  1355.     d2 = sqrt(d2);
  1356.   }
  1357.   else
  1358.   {
  1359.     d1 = sqrt(d1);
  1360.     d2 = 0.5 * q / d1;
  1361.   }
  1362.  
  1363.   /* Set up useful values for the quadratic factors */
  1364.  
  1365.   q1 = d1 * d1;
  1366.   q2 = -0.25 * c1;
  1367.  
  1368.   i = 0;
  1369.  
  1370.   /* Solve the first quadratic */
  1371.  
  1372.   p = q1 - 4.0 * (z - d2);
  1373.  
  1374.   if (p == 0)
  1375.   {
  1376.     results[i++] = -0.5 * d1 - q2;
  1377.   }
  1378.   else
  1379.   {
  1380.     if (p > 0)
  1381.     {
  1382.       p = sqrt(p);
  1383.       results[i++] = -0.5 * (d1 + p) + q2;
  1384.       results[i++] = -0.5 * (d1 - p) + q2;
  1385.     }
  1386.   }
  1387.  
  1388.   /* Solve the second quadratic */
  1389.  
  1390.   p = q1 - 4.0 * (z + d2);
  1391.  
  1392.   if (p == 0)
  1393.   {
  1394.     results[i++] = 0.5 * d1 - q2;
  1395.   }
  1396.   else
  1397.   {
  1398.     if (p > 0)
  1399.     {
  1400.       p = sqrt(p);
  1401.       results[i++] = 0.5 * (d1 + p) + q2;
  1402.       results[i++] = 0.5 * (d1 - p) + q2;
  1403.     }
  1404.   }
  1405.  
  1406.   return(i);
  1407. }
  1408. #endif
  1409.  
  1410.  
  1411.  
  1412. /*****************************************************************************
  1413. *
  1414. * FUNCTION
  1415. *
  1416. *   polysolve
  1417. *
  1418. * INPUT
  1419. *   
  1420. * OUTPUT
  1421. *   
  1422. * RETURNS
  1423. *   
  1424. * AUTHOR
  1425. *
  1426. *   Alexander Enzmann
  1427. *   
  1428. * DESCRIPTION
  1429. *
  1430. *   Root solver based on the Sturm sequences for a polynomial.
  1431. *
  1432. * CHANGES
  1433. *
  1434. *   -
  1435. *
  1436. ******************************************************************************/
  1437.  
  1438. static int polysolve(order, Coeffs, roots)
  1439. int order;
  1440. DBL *Coeffs, *roots;
  1441. {
  1442.   polynomial sseq[MAX_ORDER+1];
  1443.   DBL min_value, max_value;
  1444.   int i, nroots, np, atmin, atmax;
  1445.  
  1446.   /* Put the coefficients into the top of the stack. */
  1447.  
  1448.   for (i = 0; i <= order; i++)
  1449.   {
  1450.     sseq[0].coef[order-i] = Coeffs[i];
  1451.   }
  1452.  
  1453.   /* Build the Sturm sequence */
  1454.  
  1455.   np = buildsturm(order, &sseq[0]);
  1456.  
  1457.   /* Get the total number of visible roots */
  1458.  
  1459.   if ((nroots = visible_roots(np, sseq, &atmin, &atmax)) == 0)
  1460.   {
  1461.     return(0);
  1462.   }
  1463.  
  1464.   /* Bracket the roots */
  1465.  
  1466.   min_value = 0.0;
  1467.   max_value = Max_Distance;
  1468.  
  1469.   atmin = numchanges(np, sseq, min_value);
  1470.   atmax = numchanges(np, sseq, max_value);
  1471.  
  1472.   nroots = atmin - atmax;
  1473.  
  1474.   if (nroots == 0)
  1475.   {
  1476.     return(0);
  1477.   }
  1478.  
  1479.   /* perform the bisection. */
  1480.  
  1481.   return(sbisect(np, sseq, min_value, max_value, atmin, atmax, roots));
  1482. }
  1483.  
  1484.  
  1485.  
  1486. /*****************************************************************************
  1487. *
  1488. * FUNCTION
  1489. *
  1490. *   Solve_Polynomial
  1491. *
  1492. * INPUT
  1493. *
  1494. *   n       - order of polynomial
  1495. *   c       - coefficients
  1496. *   r       - roots
  1497. *   sturm   - TRUE, if sturm should be used for n=3,4
  1498. *   epsilon - Tolerance to discard small root
  1499. *   
  1500. * OUTPUT
  1501. *
  1502. *   r
  1503. *   
  1504. * RETURNS
  1505. *
  1506. *   int - number of roots found
  1507. *   
  1508. * AUTHOR
  1509. *
  1510. *   Dieter Bayer
  1511. *   
  1512. * DESCRIPTION
  1513. *
  1514. *   Solve the polynomial equation
  1515. *
  1516. *     c[0] * x ^ n + c[1] * x ^ (n-1) + ... + c[n-1] * x + c[n] = 0
  1517. *
  1518. *   If the equation has a root r, |r| < epsilon, this root is eliminated
  1519. *   and the equation of order n-1 will be solved. This will avoid the problem
  1520. *   of "surface acne" in (most) cases while increasing the speed of the
  1521. *   root solving (polynomial's order is reduced by one).
  1522. *
  1523. *   WARNING: This function can only be used for polynomials if small roots
  1524. *   (i.e. |x| < epsilon) are not needed. This is the case for ray/object
  1525. *   intersection tests because only intersecions with t > 0 are valid.
  1526. *
  1527. *   NOTE: Only one root at x = 0 will be eliminated.
  1528. *
  1529. *   NOTE: If epsilon = 0 no roots will be eliminated.
  1530. *
  1531. *
  1532. *   The method and idea for root elimination was taken from:
  1533. *
  1534. *     Han-Wen Nienhuys, "Polynomials", Ray Tracing News, July 6, 1994,
  1535. *     Volume 7, Number 3
  1536. *
  1537. *
  1538. * CHANGES
  1539. *
  1540. *   Jul 1994 : Creation.
  1541. *
  1542. ******************************************************************************/
  1543.  
  1544. int Solve_Polynomial(n, c0, r, sturm, epsilon)
  1545. int n, sturm;
  1546. DBL *c0, *r, epsilon;
  1547. {
  1548.   int roots, i;
  1549.   DBL *c;
  1550.  
  1551.   Increase_Counter(stats[Polynomials_Tested]);
  1552.  
  1553.   roots = 0;
  1554.  
  1555.   /*
  1556.    * Determine the "real" order of the polynomial, i.e.
  1557.    * eliminate small leading coefficients.
  1558.    */
  1559.  
  1560.   i = 0;
  1561.  
  1562.   while ((fabs(c0[i]) < COEFF_LIMIT) && (i < n))
  1563.   {
  1564.     i++;
  1565.   }
  1566.  
  1567.   n -= i;
  1568.  
  1569.   c = &c0[i];
  1570.  
  1571.   switch (n)
  1572.   {
  1573.     case 0:
  1574.  
  1575.       break;
  1576.  
  1577.     case 1:
  1578.  
  1579.       /* Solve linear polynomial. */
  1580.  
  1581.       if (c[0] != 0.0)
  1582.       {
  1583.         r[roots++] = -c[1] / c[0];
  1584.       }
  1585.  
  1586.       break;
  1587.  
  1588.     case 2:
  1589.  
  1590.       /* Solve quadratic polynomial. */
  1591.  
  1592.       roots = solve_quadratic(c, r);
  1593.  
  1594.       break;
  1595.  
  1596.     case 3:
  1597.  
  1598.       /* Root elimination? */
  1599.  
  1600.       if (epsilon > 0.0)
  1601.       {
  1602.         if ((c[2] != 0.0) && (fabs(c[3]/c[2]) < epsilon))
  1603.         {
  1604.           Increase_Counter(stats[Roots_Eliminated]);
  1605.  
  1606.           roots = solve_quadratic(c, r);
  1607.  
  1608.           break;
  1609.         }
  1610.       }
  1611.  
  1612.       /* Solve cubic polynomial. */
  1613.       if (sturm)
  1614.       {
  1615.         roots = polysolve(3, c, r);
  1616.       }
  1617.       else
  1618.       {
  1619.         roots = solve_cubic(c, r);
  1620.       }
  1621.  
  1622.       break;
  1623.  
  1624.     case 4:
  1625.  
  1626.       /* Root elimination? */
  1627.  
  1628.       if (epsilon > 0.0)
  1629.       {
  1630.         if ((c[3] != 0.0) && (fabs(c[4]/c[3]) < epsilon))
  1631.         {
  1632.           Increase_Counter(stats[Roots_Eliminated]);
  1633.  
  1634.           if (sturm)
  1635.           {
  1636.             roots = polysolve(3, c, r);
  1637.           }
  1638.           else
  1639.           {
  1640.             roots = solve_cubic(c, r);
  1641.           }
  1642.  
  1643.           break;
  1644.         }
  1645.       }
  1646.  
  1647.       /* Test for difficult coeffs. */
  1648.  
  1649.       if (difficult_coeffs(4, c))
  1650.       {
  1651.         sturm = TRUE;
  1652.       }
  1653.  
  1654.       /* Solve quartic polynomial. */
  1655.  
  1656.       if (sturm)
  1657.       {
  1658.         roots = polysolve(4, c, r);
  1659.       }
  1660.       else
  1661.       {
  1662.         roots = solve_quartic(c, r);
  1663.       }
  1664.  
  1665.       break;
  1666.  
  1667.     default:
  1668.  
  1669.       if (epsilon > 0.0)
  1670.       {
  1671.         if ((c[n-1] != 0.0) && (fabs(c[n]/c[n-1]) < epsilon))
  1672.         {
  1673.           Increase_Counter(stats[Roots_Eliminated]);
  1674.  
  1675.           roots = polysolve(n-1, c, r);
  1676.         }
  1677.       }
  1678.  
  1679.       /* Solve n-th order polynomial. */
  1680.  
  1681.       roots = polysolve(n, c, r);
  1682.  
  1683.       break;
  1684.   }
  1685.  
  1686.   return(roots);
  1687. }
  1688.